﻿#region

using System.Drawing;
using MediaSage.Lib.Configuration;
using MediaSage.Lib.Utilities;
using NHibernate;
using NHibernate.Criterion;
using WatTmdb.V3;

#endregion

namespace MediaSage.Lib.Database
{
    public class Database
    {
        #region Fields

        private static readonly object lockObject = new object();
        protected Config config;
        protected Logger logger;

        #endregion Fields

        #region Constructors

        public Database(Config Config)
        {
            config = Config;
            logger = Config.Logger;
            DBUtil.GetSession().Flush();
        }

        ~Database()
        {
        }

        #endregion Constructors

        #region Methods

        public MediaClass GetMovieByTMDBID(int ID)
        {
            logger.Log("Entering Database.GetMovieByTMDBID(" + ID + ")");
            lock (lockObject)
            {
                var vi =
                    DBUtil.GetSession().CreateCriteria<VideoEntity>().Add(Restrictions.Eq("TmdbID", ID)).UniqueResult
                        <VideoEntity>();
                if (vi == null)
                {
                    logger.Log("Movie not in database");
                    logger.Log("Exiting Database.GetMovieByTMDBID(" + ID + ")");

                    return null;
                }
                var mc = new MediaClass(config);
                mc.videoEntity = vi;

                logger.Log("Exiting Database.GetMovieByTMDBID(" + ID + ")");
                return mc;
            }
        }

        /// <summary>
        ///     Checks to see if the image exists in the database, if it does, it returns the Object for the Image, null if does not exist
        /// </summary>
        /// <param name="Image"> </param>
        /// <returns> </returns>
        public ImageEntity ImageExists(Image Image)
        {
            logger.Log("Entering Database.ImageExists(IMG)");

            lock (lockObject)
            {
                ISession session = DBUtil.GetSession();
                byte[] md5 = ImageUtils.GenerateMD5HashFromImage(Image);
                if (md5 == null)
                {
                    logger.Log(Logger.Levels.ERROR, "Failed to generate MD5 Hash from Image");
                    return (null);
                }

                var ie =
                    session.CreateCriteria(typeof(ImageEntity)).Add(Restrictions.Eq("HashCode", md5)).UniqueResult
                        <ImageEntity>();
                if (ie == null)
                {
                    logger.Log("Image is not in the database");
                    logger.Log("Exiting Database.ImageExists(IMG), rc==null");
                    return (null);
                }
                logger.Log("Exiting Database.ImageExists(IMG), rc==imgPtr");
                return ie;
            }
        }

        public PersonEntity PersonExists(string IMDBId)
        {
            logger.Log("Entering Database.PersonExists(" + IMDBId + ")");
            lock (lockObject)
            {
                ISession session = DBUtil.GetSession();
                var pe =
                    session.CreateCriteria(typeof(PersonEntity)).Add(Restrictions.Eq("IMDBID", IMDBId)).UniqueResult
                        <PersonEntity>();
                if (pe == null)
                {
                    logger.Log("Person is not in the database");
                    logger.Log("Exiting Database.PersonExists(" + IMDBId + ")");
                    return null;
                }
                logger.Log("Exiting Database.PersonExists(" + IMDBId + ")");
                return pe;
            }
        }

        public PersonEntity PersonExists(Cast CastPerson)
        {
            logger.Log("Entering Database.PersonExists(TmdbCastPerson,API)");
            lock (lockObject)
            {
                ISession session = DBUtil.GetSession();
                PersonEntity pe = null;
                if (!config.MergeOnPersonName)
                {
                    pe =
                        session.CreateCriteria(typeof(PersonEntity)).Add(Restrictions.Eq("TMDBID", CastPerson.id)).
                            UniqueResult<PersonEntity>();
                }
                else
                {
                    pe =
                        session.CreateCriteria(typeof(PersonEntity)).Add(Restrictions.Eq("Name", CastPerson.name)).
                            UniqueResult<PersonEntity>();
                }

                if (pe == null)
                {
                    logger.Log("Person is not in the database");
                    logger.Log("Exiting Database.PersonExists(" + CastPerson.id + ")");
                    return null;
                }
                logger.Log("Exiting Database.PersonExists(" + CastPerson.id + ")");
                return pe;
            }
        }

        #endregion Methods
    }
}